import os
import json
from .http_client import HttpClient
from concurrent.futures import ThreadPoolExecutor
from .part_tag import PartTag
from .logger import get_logger
from .errors import XVODClientError

class XstoreVodClient(object):
    def __init__(self, access_key, secret_key, endpoint: str = 'https://vod-api.xstore.ctyun.cn', max_workers: int = 10):
        self.httpclient = HttpClient(endpoint, access_key, secret_key)
        self.thread_pool = ThreadPoolExecutor(thread_name_prefix="vod-upload-thread-", max_workers=max_workers)

    def multipart_upload(self, filepath: str, name: str = '', part_size: int = 1024 * 1024 * 5) -> dict:
        """
        分片上传请求。

        参数:
        - filepath: str, 文件路径。
        - part_size: int, 分片大小。

        返回:
        - dict
          {
           "code": "0",
           "message": "",
           "data": {
              "videoId": "dwdssdsad",
              "videoUrl": "http://jjdwuuueuu"
           }
          }
        异常：
        - 分片、上传分片、合并分片可能会抛的异常
        """
        if part_size < 1024 * 1024 * 5 or part_size > 1024 * 1024 * 100:
            get_logger().error("part_size must large than 1024 * 1024 * 5 and less than 1024 * 1024 * 100")
            raise XVODClientError("part_size must large than 1024 * 1024 * 5 and less than 1024 * 1024 * 100")
        etags = []
        futures = []
        length = os.path.getsize(filepath)
        if name == '':
            with open(filepath, 'rb') as file:
                name = file.name
        res = self.httpclient.post('/xstore-vod/video/create', data={"name": name,
                                                                     "fileInfo": {"PART_SIZE_MIN_M": 5,
                                                                                  "PART_SIZE_MAX_M": 100,
                                                                                  "PART_SIZE_MIN": 5 * 1024 * 1024,
                                                                                  "PART_SIZE_MAX": 100 * 1024 * 1024,
                                                                                  "DEFAULT_PART_SIZE": 8 * 1024 * 1024,
                                                                                  "fileSize": length,
                                                                                  "partSize": part_size}})
        data = res.get('data')
        video_id = data.get('videoId')
        urls = data.get('uploadUrls')
        for i, url in enumerate(urls):
            url = urls[i]
            future = self.thread_pool.submit(self._upload, filepath, url, i, part_size)
            futures.append((i + 1, future))

        for part_num, future in futures:
            try:
                etag = future.result()
                etags.append(PartTag(part_num, etag))
            except Exception as e:
                raise XVODClientError(f"Failed to upload part {part_num}: {e}", ori_exception=e)
        people_list = [etag.to_dict() for etag in etags]
        json_str = json.dumps(people_list, indent=2)
        return self.httpclient.post('/xstore-vod/video/create/complete',
                             data={'videoId': video_id, 'etags': json.loads(json_str)})


    def _upload(self, file_path: str, url: str, part_num: int, part_size: int) -> str:
        with open(file_path, 'rb') as f:
            f.seek(part_num * part_size)
            # 读取指定大小的数据块
            part_data = f.read(part_size)
        headers = self.httpclient.put(url, part_data, headers={})
        return headers.get('ETag')


    def create_transcode_task(self, video_id: str, transcode_template_id: list[int], watermark_template: int = '',
                              callback: str = '', default_transcode_template: bool = False,
                              default_watermark_template: bool = False) -> list[str]:
        """
        发起转码任务。

        参数:
        - video_id: str, 媒体id。
        - transcode_template_id: list[int], 转码模板id列表。
        - watermark_template: int, 水印模板id。
        - callback: str, 回调地址。
        - default_transcode_template: bool, 是否使用默认转码模板。
        - default_watermark_template: bool, 是否使用默认水印模板。
        返回:
        - transcodeTaskIds list[str]  转码任务列表。
        """
        res = self.httpclient.post('/xstore-vod/task/submit', data={'videoId': video_id,
                                                                     'useDefaultTranscodeTemplate': default_transcode_template,
                                                                     'transcodeTemplates': transcode_template_id,
                                                                     'useDefaultWatermarkTemplate': default_watermark_template,
                                                                     'watermarkTemplate': watermark_template,
                                                                     'callback': callback})
        data = res.get('data')
        return  data.get('transcodeTaskIds')

    def _se_upload(self, url, part_data):
        headers = self.httpclient.put(url, part_data, headers={})
        return headers.get('ETag')
